package com.dw.etl.core.service;

import com.dw.etl.common.base.BaseException;
import com.dw.etl.common.util.SnowflakeIdWorker;
import com.dw.etl.common.vo.FieldAttrVO;
import com.dw.etl.common.vo.PaginationVO;
import com.dw.etl.core.api.*;
import com.dw.etl.core.bean.model.BaseDb;
import com.dw.etl.core.bean.model.BaseDbTpcomp;
import com.dw.etl.core.bean.model.EtlBase;
import com.dw.etl.core.bean.vo.TableVO;
import com.dw.etl.core.utils.EtlUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.dw.etl.core.mapper.EtlBaseFieldMapper;
import com.dw.etl.core.bean.model.EtlBaseField;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * etlBaseField服务实现类
 * Created by hozeData on 2021/05/28.
 */
@Service
@Transactional
public class EtlBaseFieldServiceImpl implements EtlBaseFieldService{

    private static final Logger LOGGER = LoggerFactory.getLogger(EtlBaseFieldServiceImpl.class);

    @Autowired
    private EtlBaseFieldMapper etlBaseFieldMapper;

    @Override
    public int insert(EtlBaseField etlBaseField) {
        if(etlBaseField.getIdFld()==null){
            Long uuid32 = SnowflakeIdWorker.getId();
            etlBaseField.setIdFld(uuid32);
        }
        return etlBaseFieldMapper.insert(etlBaseField);
    }

    @Override
    public int insertSelective(EtlBaseField etlBaseField)  {
        if(etlBaseField.getIdFld()==null){
            Long uuid32 = SnowflakeIdWorker.getId();
            etlBaseField.setIdFld(uuid32);
        }
        return etlBaseFieldMapper.insertSelective(etlBaseField);
    }

    @Override
    public int deleteById(Long idFld)  {
        return etlBaseFieldMapper.deleteByPrimaryKey(idFld);
    }

    @Override
    public int updateByIdSelective(EtlBaseField etlBaseField)  {

        return etlBaseFieldMapper.updateByPrimaryKeySelective(etlBaseField);
    }

    @Override
    public int updateById(EtlBaseField etlBaseField)  {
        return etlBaseFieldMapper.updateByPrimaryKey(etlBaseField);
    }

    @Override
    public EtlBaseField getById(Long idFld)  {
        return etlBaseFieldMapper.selectByPrimaryKey(idFld);
    }

    @Override
    public List<EtlBaseField> findByModel(EtlBaseField etlBaseField)  {
        return etlBaseFieldMapper.findByModel(etlBaseField);
    }

    @Override
    public PaginationVO<EtlBaseField> findPageByModel(EtlBaseField etlBaseField, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum == null? 1 : pageNum, pageSize == null? 10 : pageSize);
        List<EtlBaseField> quesList = etlBaseFieldMapper.findByModel(etlBaseField);
        PageInfo<EtlBaseField> pageInfo = new PageInfo<>(quesList);
        PaginationVO<EtlBaseField> paginationVo = new PaginationVO(pageInfo.getTotal(), pageInfo.getList());
        return paginationVo;
    }

    @Override
    public int save(List<EtlBaseField> list) {
        EtlBaseField modelField = new EtlBaseField();
        modelField.setIdBase(list.get(0).getIdBase());
        etlBaseFieldMapper.deleteByModel(modelField);
        for(EtlBaseField etlBaseField:list) {
            int num ;
            if(etlBaseField.getIdFld()==null) {
                num = this.insertSelective(etlBaseField);
            } else {
                num = this.updateByIdSelective(etlBaseField);
            }
        }
        return 0;
    }

    @Autowired
    EtlBaseService etlBaseService;
    @Autowired
    BaseDbService baseDbService;
    @Autowired
    TableOperService tableOperService;
    @Autowired
    BaseDbTpcompService baseDbTpcompService;

    /**
     * //field 写法有 (表名/表简称).字段+（as/' '）+别名，或者变量+（as/' '）+别名
     * 从sql中提取字段的逻辑为根据字段名获取长度与精度，最后返回别名的长度与精度。匹配不上的为空
     *
     * 1.根据as或者空格切分字段字符串，长度为1的说明没别名，长度为2的前面是字段名后面是别名
     * 2.字段名以.分割获取最后的字段
     * 3.别名+精度封装成VO返回
     *
     * @param sql
     * @param dbtp
     * @return
     */
    public List<EtlBaseField> findFieldMsg(Long idBase) throws BaseException {
        EtlBase etlBase = etlBaseService.getById(idBase);
        BaseDb baseDb = baseDbService.getById(etlBase.getIdDbSou());
        TableVO tableVO = EtlUtil.findTbsAndFldsFromSql(etlBase.getQsql());
        String[] fields = tableVO.getFields();
        if(fields==null ||fields.length==0) {
            return null;
        }
        List<FieldAttrVO> list = tableOperService.findFieldMsgFromDb(baseDb,tableVO.getTableName());
        List<EtlBaseField> etlBaseFieldList = new ArrayList<>();
        BaseDbTpcomp tpcompModel = new BaseDbTpcomp();
        tpcompModel.setEuDbtp(baseDb.getEuTp());
        List<BaseDbTpcomp> dbTpcompList = baseDbTpcompService.findByModel(tpcompModel);
        Map<String,BaseDbTpcomp> dbTpcompMap = new HashMap<>();
        for(BaseDbTpcomp comp:dbTpcompList) {
            dbTpcompMap.put(comp.getEuFldtp(),comp);
        }
        if(list!=null &&list.size()>0) {
            Map<String,FieldAttrVO> fieldAttrMap = new HashMap<>();
            for(FieldAttrVO attrVO:list) {
                fieldAttrMap.put(attrVO.getField(),attrVO);
            }
            FieldAttrVO attrVO;EtlBaseField etlBaseField;
            String arr[],arr2[],alias = null,field = null;
            for(String fullField:fields) {
                fullField = fullField.trim();
                if(StringUtils.isEmpty(fullField)) {
                    continue;
                }
                alias = null;field = null;arr=null;
                if(fullField.contains(" as ")) {
                    arr = fullField.split(" as ");
                } else if(fullField.contains(" ")) {
                    arr = fullField.split(" ");
                } else {
                    field = fullField;
                }
                if(arr!=null) {
                    field = arr[0];
                    if(arr.length>1) {
                        alias = arr[1];
                    }
                }
                if(field.contains(".")) {
                    arr2 = field.split(".");//去除表名.字段带来的影响
                    field = arr2[arr2.length-1];
                }
                attrVO = fieldAttrMap.get(field);
                etlBaseField = new EtlBaseField();
                etlBaseField.setIdBase(idBase);
                etlBaseField.setField(alias==null?field:alias);
                etlBaseField.setTbName(tableVO.getTableName());
                if(attrVO!=null) {
                    tpcompModel = dbTpcompMap.get(attrVO.getEuType().toUpperCase());
                    if(tpcompModel==null) {
                        // TODO 此处为异常，说明数据库字段不全,字段长度需要统一修正为long
                    } else {
                        etlBaseField.setEuType(tpcompModel.getEuJavatp());
                        etlBaseField.setNumLength(attrVO.getNumLength()==null?Integer.parseInt(tpcompModel.getNumLength()+""):attrVO.getNumLength());
                        if(tpcompModel.getFgDeci()>0) { //说明该类型是小数
                            if(attrVO.getNumPrec()==null || attrVO.getNumPrec()==0) {
                                etlBaseField.setNumPrec(tpcompModel.getFgDeci());
                            } else {
                                etlBaseField.setNumPrec(Byte.parseByte(attrVO.getNumPrec()+""));
                            }
                        } else {
                            etlBaseField.setNumPrec((byte)0);
                        }
                    }
                }
                etlBaseFieldList.add(etlBaseField);
            }
        }
        return etlBaseFieldList;
    }
}
